#include "aimage.h"
#include "aimage_utils.h"
#include "aimage_ppm.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>

int AIMAGE::starfind( float cutoff, ASTAR_FIELD &stars )
{
	int star = 0;
	int y;
	int width, height;

	makemask( cutoff );

#ifdef DEBUG
	AIMAGE_PPM_UTILS::save( *this, "debug_mask.ppm" );
#endif

	AFLOOD_DATA flood_data;

	flood_data.rs = FULL_INT;
	flood_data.gs = FULL_INT;
	flood_data.bs = FULL_INT;
	flood_data.rd = 0;
	flood_data.gd = 0;
	flood_data.bd = (rand() % (FULL_INT/2)) + FULL_INT/2;
	flood_data.num_pixels = 0;
	flood_data.xc = 0;
	flood_data.yc = 0;

	get_dim( width, height );

	for ( y = 0; y < height; ++y )
	{
		int x;
		for ( x = 0; x < width; ++x )
		{
			floodfill( x, y, flood_data );
			if ( flood_data.num_pixels > 5 )
			{
				if ( star < stars.get_max_stars() )
				{
					float xc, yc;
					float r;
					float minrad = 0, maxrad = 0;
					bool hole_found = false;
	
					xc = (( float ) flood_data.xc) / (( float ) flood_data.num_pixels) + 0.5;
					yc = (( float ) flood_data.yc) / (( float ) flood_data.num_pixels) + 0.5;

					for ( r = 1.0; r < 30.0; ++r )
					{
						float d = M_PI * r * 2;
						float a;
						bool one_found = false;
						bool all_found = true;
						for ( a = 0.0f; a < M_PI * 2; a+= M_PI * 2 / d )
						{
							float x, y;
							APIXEL p;
							x = xc + cos( a ) * r;
							y = yc + sin( a ) * r;

							if ( x < 0 || y < 0 || x >= m_width || y >= m_height )
								continue;

							getpixel( ( int ) x, (int) y, p );

							if ( 	p.r == flood_data.rd && 
									p.g == flood_data.gd && 
									p.b == flood_data.bd )
							{
								one_found = true;
							}
							else
							{
								all_found = false;
								hole_found = true;
							}
						}
						if ( all_found && !hole_found )
						{
							minrad = r;
						}
						if ( one_found )
						{
							maxrad = r;
						}
						if ( !one_found )
						{
							break;
						}
					}

					ASTAR_DATA mystar;

					mystar.xc = xc;
					mystar.yc = yc;
					mystar.minrad = minrad;
	 				mystar.maxrad= maxrad;
					mystar.pixels= flood_data.num_pixels;

					stars.set_star( star, mystar );

					star++;
				}
			}
			flood_data.rd = 0;
			flood_data.gd = 0;
			flood_data.bd = (rand() % (FULL_INT/2)) + FULL_INT/2;
			flood_data.xc = 0;
			flood_data.yc = 0;
			flood_data.num_pixels = 0;
		}
	}
	return star;
}

void AIMAGE::drawstars( ASTAR_FIELD &stars, APIXEL tint )
{
	int i;
	int num_stars;
	APIXEL red, green, white;

    red.r = FULL_INT/2; red.g = FULL_INT/2; red.b = FULL_INT/2;
    green.r = FULL_INT; green.g = FULL_INT; green.b = FULL_INT;
    white.r = FULL_INT; white.g = FULL_INT; white.b = FULL_INT;

	red = blend_colors( red, tint );
	green = blend_colors( green, tint );
	white = blend_colors( white, tint );

	num_stars = stars.get_num_stars();

	for ( i = 0; i < num_stars; ++i )
	{
		const ASTAR_DATA &star = stars.get_star( i );

        //circle( star.xc, star.yc, star.minrad, red , false );
        circle( star.xc, star.yc, star.maxrad, green, false );
        circle( star.xc, star.yc, star.maxrad +.5, green, false );
        circle( star.xc, star.yc, star.maxrad +1, green, false );
        circle( star.xc, star.yc, star.maxrad +1.5, green, false );
        circle( star.xc, star.yc, star.maxrad +2., green, false );

		if ( star.xc >= 0 && star.yc >= 0 && star.xc < m_width && star.yc < m_height )
		{
        	setpixel( star.xc, star.yc, white );
		}
	}
}

void AIMAGE::make_congestion_map( const AIMAGE &src, const ASTAR_FIELD &stars, bool border_only )
{
	int new_width, new_height;
	int i;
	int num_stars;
	APIXEL full;
	APIXEL partial;
	APIXEL border;

	full.r = 5000; full.g = 5000; full.b = 5000; 
	partial.r = 2000; partial.g = 2000; partial.b = 2000; 
	border.r = FULL_INT; border.g = FULL_INT; border.b = FULL_INT; 

	src.get_dim( new_width, new_height );

	new_width = new_width / congestion_scale + 1;
	new_height = new_height / congestion_scale + 1;
	num_stars = stars.get_num_stars();

	alloc_image( new_width, new_height );
	AIU::cls( *this, 0, 0, 0 );

	if ( !border_only )
	{
	for ( i = 0; i < num_stars; ++i )
	{
		int xs;
		int xint, yint;
		const ASTAR_DATA &star = stars.get_star( i );

		xint = (int) star.xc;
		yint = (int) star.yc;

		xint /= congestion_scale;
		yint /= congestion_scale;

		for ( xs = xint - 3; xs <= xint + 3; ++xs )
		{
			int ys;
			for ( ys = yint - 3; ys <= yint + 3; ++ys )
			{
		//		if ( xs < 0 || ys < 0 || xs >=m_width || ys >= m_height )
		//		{
		//			continue;
		//		} 
				raisepixel( xs, ys, full );
			}
		}
		//raisepixel( xint + 1, yint, partial );
		//raisepixel( xint - 1, yint, partial );
		//raisepixel( xint, yint - 1, partial );
		//raisepixel( xint, yint + 1, partial );
	}
	}

	int x, y;

	for ( x = 0; x < m_width; ++x )
	{
		raisepixel( x, 0, border );
		raisepixel( x, 1, border );
		raisepixel( x, m_height-1, border );
		raisepixel( x, m_height-2, border );
	}
	for ( y = 0; y < m_height; ++y )
	{
		raisepixel( 0, y, border );
		raisepixel( 1, y, border );
		raisepixel( m_width-1, y, border );
		raisepixel( m_width-2, y, border );
	}
}

